Click here to return to the VHDL Reference Guide. (last edit: 24. september 2012)

Function

Used to group together executable, sequential statements to define new mathematical or logical functions. Also used to define bus resolution functions, operators, and conversion functions between data types. When defined in a package, the function must be split into a declaration and a body.

Syntax

 {declaration}
 [Kind] function FunctionName
                                    [(ParameterDeclaration; ...)]
                                    return TypeName;

 {body}
 [Kind] function FunctionName
                                    [(ParameterDeclaration; ...)]
                                    return TypeName is
   Declarations...
 begin
   SequentialStatements...end [function] [FunctionName];

 Kind = {either} pure impure

 ParameterDeclaration = {either}
 constant ConstantName,... :[in] DataType [:= Expression]
 signal   SignalName, ...  :[in] DataType [:= Expression]
 file FileName, ... : DataType
    

Where

See Declaration A Function Body is not allowed in a Package Declaration.

Rules

The FunctionName may be an identifier or an operator. Functions cannot assign signals or variables defined outside themselves, nor can then contain wait statements. A function must execute a return statement. Pure functions cannot have side effects - they must do nothing but return a value.

Things to remember

The return type must be a name; it cannot include a constraint. Variables defined inside a function are initialized each time the function is called. The declaration and body must conform, i.e. the parameters and return type must be identical between the two. The function declaration ends with a ";", whereas the function body has is at the corresponding point in the syntax.

Synthesis

Each call to a function is synthesized as a separate block of combinational logic.

Tips

Parameters may be unconstrained arrays; you can use array attributes (e.g. 'RANGE) to find their bounds.

Example

  package P is

  function To_Std_logic_vector (Value, Width: INTEGER)
           return Std_logic_vector;

  function "+" (A, B: Std_logic_vector)
                return Std_logic_vector is
  end;

  package body P is

  function To_Std_logic_vector (Value, Width: INTEGER)
           return Std_logic_vector is
    variable V: INTEGER := Value;
    variable Result: Std_logic_vector (1 to Width);
  begin
    for I in Result'REVERSE_RANGE loop
      if V mod 2 = 1 then
        Result(I) := '1';
      else
        Result(I) := '0';
      end if;
      if V >= 0 then
        V := V / 2;
      else
        V := (V - 1) / 2;
      end if;
    end loop;
    return Result;
  end To_Std_logic_vector;

  function "+" (A, B: Std_logic_vector)
                return Std_logic_vector is
    variable LV: Std_logic_vector(A'Length-1 downto 0);
    variable RV: Std_logic_vector(B'Length-1 downto 0);
    variable Result: 
                 Std_logic_vector(A'Length-1 downto 0);
    variable Carry: Std_logic := '0';
  begin
    LV := A;
    RV := B;
    assert A'Length = B'Length
      report "function +: operands have different widths"
      severity Failure;
    for I in Result'Reverse_range loop
      Result(I) := LV(I) xor RV(I) xor Carry;
      Carry := (LV(I) and RV(I)) or (LV(I) and Carry) or
               (RV(I) and Carry); 
    end loop;
    return Result;
  end "+";

  end P;
    

See Also

Function Call, Return, Procedure, Package, Type Conversion, Operator